package com.ztp.pc.gui.gtabpane;

import static java.lang.System.out;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.HashSet;
import java.util.Iterator;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;

import com.ztp.pc.gui.gtabpane.GTabButton.TabButtonActionListener;


public class GTabHeader extends JPanel {
	static HashSet<GTabHeader> tabHeaders = new HashSet<GTabHeader>();
	
	private static final long serialVersionUID = 2852950343825764942L;
	public static final int DEF_BTN_CLOSE 	= 0;
	public static final int DEF_BTN_MINIM 	= 1;
	public static final int DEF_BTN_MAXIM 	= 2;
	public static final int DEF_BTN_NEW 	= 3;
	
	private Box lewyBox;
	private Box prawyBox;
	private JScrollPane scrollPane;
	private JPanel lewyPanel;
	
	private GTabButton selectedButton;
	private GTabButton focusedButton;
	private GTabButton lastPressedButton;
	

	public GTabHeader (){
		tabHeaders.add(this);
		this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
		this.setPreferredSize(new Dimension(10, 24));
		
		
		lewyPanel = new JPanel();
		lewyPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
		lewyPanel.addMouseListener(tabHeaderMouseListener);
		lewyPanel.addMouseMotionListener(tabHeaderMotionListener);
		
		scrollPane = new JScrollPane();
		scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
		scrollPane.getHorizontalScrollBar().setPreferredSize(new Dimension(0, 0));
		scrollPane.getHorizontalScrollBar().setUnitIncrement(10);
		scrollPane.setViewportView(lewyPanel);
		
		lewyBox = Box.createHorizontalBox();
		lewyBox.add(scrollPane);
		
		prawyBox = Box.createHorizontalBox();
		
		this.add(lewyBox);
		this.add(prawyBox);
	}
	
	public void addTabButton(GTabButton tb){
		if(lewyPanel.getComponents().length == 0){
			selectedButton = tb;
			tb.invokeSelect();
		}
		tb.addTabBtnActionListener(tabButtonsActions);
		lewyPanel.add(tb);
	}
	
	public void addTabButtonAt(GTabButton tb, int index){
		if(lewyPanel.getComponents().length == 0){
			selectedButton = tb;
			tb.invokeSelect();
		}
		tb.addTabBtnActionListener(tabButtonsActions);
		lewyPanel.add(tb,index);
	}
	
	public void removeTabButton(GTabButton gtb){
		lewyPanel.remove(gtb);
		gtb.removeTabBtnActionListener(tabButtonsActions);
		if(lewyPanel.getComponents().length != 0){
			((GTabButton)lewyPanel.getComponents()[0]).invokeSelect(); // select firs comp after remove
		}
		this.repaint();
	}
	
	GTabButton removeTabButton(String linkedCardId){
		Component [] comps = lewyPanel.getComponents();
		for(Component c : comps){
			GTabButton gtb = (GTabButton)c;
			if(gtb.getLinkedCardId().equals(linkedCardId)){
				removeTabButton(gtb);
				return gtb;
			}
		}
		return null;
	}
	
	public void addCtrlComponent(Component comp){
		prawyBox.add(comp);
	}
	
	private void removeBorderAfterRelase(Component relasedComponent){
		if(relasedComponent instanceof GTabButton){
			GTabButton temp =(GTabButton)relasedComponent;
			temp.tabBtnMouseListener.mouseReleased(null);
		}
		if(GTabHeader.this.focusedButton != null){
			GTabHeader.this.focusedButton.disableFocus();
		}
		
		GTabHeader.this.focusedButton = null;
	}
	
	private void interHeaderExchange(GTabButton relasedButton, GTabHeader relasedButtonOwner){
		GTabButton exchButton = this.lastPressedButton;
		this.lewyPanel.remove(exchButton);
		
		
		int relasedButtonIdx = -1;
		Component [] comps = relasedButtonOwner.lewyPanel.getComponents();
		for(int i=0;i<comps.length;i++){
			if(relasedButton == comps[i]){
				relasedButtonIdx = i;
				break;
			}
		}
		
		relasedButtonOwner.lewyPanel.add(exchButton, relasedButtonIdx);
		this.lewyPanel.revalidate();
		relasedButtonOwner.lewyPanel.revalidate();
	}
	
	//----listeners
	
	MouseListener tabHeaderMouseListener = new MouseListener() {
		@Override
		public void mouseReleased(MouseEvent e) {
			out.println("MouseListener mouseReleased "+e.getModifiers() );
			
			Component relasedComponent = lewyPanel.getComponentAt(e.getPoint());
			int lastRelasedIndex = -1;
			
			if(relasedComponent != null ){
				if(!(relasedComponent instanceof GTabButton)){
					return;
				}
				
				if(lastPressedButton == relasedComponent) {
					removeBorderAfterRelase(relasedComponent);
					return;
				}
				
				Component [] comps = lewyPanel.getComponents();
				for(int i=0;i<comps.length;i++){
					if(comps[i] == relasedComponent){
						lastRelasedIndex = i;
						break;
					}
				}
				
				lewyPanel.remove(lastPressedButton);
				lewyPanel.add(lastPressedButton, lastRelasedIndex);
				lewyPanel.revalidate();
				
				
			}
			else{
				GTabHeader relasedCompOwner = null;
				
				Iterator<GTabHeader> it = tabHeaders.iterator();
				while(it.hasNext()){
					GTabHeader next = it.next();
					Point p = new Point(e.getXOnScreen(), e.getYOnScreen());
					SwingUtilities.convertPointFromScreen(p, next);
					if(next.getBounds().contains(p) && next != GTabHeader.this){
						relasedComponent = next.lewyPanel.getComponentAt(p);
						relasedCompOwner = next;
						break;
					}
				}
				
				if(relasedComponent == null) return;
				
				Component [] comps = relasedCompOwner.lewyPanel.getComponents();
				for(int i=0;i<comps.length;i++){
					if(comps[i] == relasedComponent){
						lastRelasedIndex = i;
						break;
					}
				}
				
				Component removedCard = ((GTabPane)GTabHeader.this.getParent())
						.removeCard(lastPressedButton.getLinkedCardId());
				
				((GTabPane)relasedCompOwner.getParent()).addExistingCardAt(removedCard, lastPressedButton,lastRelasedIndex);
				GTabHeader.this.lewyPanel.revalidate();
				relasedCompOwner.lewyPanel.revalidate();
				relasedCompOwner.removeBorderAfterRelase(relasedComponent);
			}
			
			removeBorderAfterRelase(relasedComponent);
		}
		@Override
		public void mousePressed(MouseEvent e) {
			out.println("MouseListener mousePressed "+e.getModifiers() );
			Component c = lewyPanel.getComponentAt(e.getPoint());
			if(c instanceof GTabButton){
				GTabButton temp =(GTabButton)c;
				temp.tabBtnMouseListener.mousePressed(e);
				lastPressedButton = temp;
			}
		}
		@Override
		public void mouseExited(MouseEvent arg0) {
			//out.println("MouseListener mouseExited "+arg0.getModifiers());
		}
		@Override
		public void mouseEntered(MouseEvent arg0) {
			//out.println("MouseListener mouseEntered "+arg0.getModifiers());
		}
		@Override
		public void mouseClicked(MouseEvent arg0) {
			//out.println("MouseListener mouseClicked "+arg0.getModifiers());
		}
	};
	
	
	private TabButtonActionListener tabButtonsActions = new TabButtonActionListener() {
		@Override
		public void onSelect(GTabButton gtb, String linkedCompId) {
			if(selectedButton != gtb){
				selectedButton.deselect();
				selectedButton = gtb;
			}
		}
		
		@Override
		public void onClose(GTabButton gtb, String linkedCompId) {
			removeTabButton(gtb);
		}
	};
	
	MouseMotionListener tabHeaderMotionListener = new MouseMotionListener() {
		@Override
		public void mouseMoved(MouseEvent arg0) {
			//out.println("MouseMotionListener mouseMoved");
		}
		@Override
		public void mouseDragged(MouseEvent arg0) {
			String name = "";
			Component c = lewyPanel.getComponentAt(arg0.getPoint());
			if( c instanceof GTabButton ){
				GTabButton gtb = (GTabButton)c;
				name = gtb.getName();
				
				if(focusedButton == gtb){
					return;
				}
				
				gtb.enableFocus();
				if(focusedButton == null){
					focusedButton = gtb;
					return;
				}
				
				focusedButton.disableFocus();
				focusedButton = gtb;
			}
			
			out.println("mouseDragged " +arg0.getPoint() 
					+ ((c != null)? c.toString():"c null")
					);
		}
	};
	
	///---------static
	
	public static JButton createDefaultButton(int buttonType){
		JButton b  = null;
		switch (buttonType) {
		case DEF_BTN_CLOSE:
			b = new JButton(Util.getDefaultCloseIcon(false));
			break;
		case DEF_BTN_MINIM:
			b = new JButton(Util.getDefaultCloseIcon(false));
			break;
		case DEF_BTN_MAXIM:
			b = new JButton(Util.getDefaultCloseIcon(false));
			break;
		case DEF_BTN_NEW:
			b = new JButton(Util.getDefaultNewIcon(false));
			break;
		}
		b.setMargin(new Insets(0, 0, 0, 0));
		b.setFocusable(false);
		//b.setBorder(BorderFactory.createEmptyBorder());
		//b.setPreferredSize(new Dimension(34, 10));
		//b.setMinimumSize(new Dimension(34, 10));
		//b.setMaximumSize(new Dimension(34, 10));
		return b;
	}
	
	
}

